package com.pi.pro.xcmg.am.was.fac.service;


import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.pi.common.CodesConstants;
import com.pi.common.utils.StringUtils;
import com.pi.core.exchange.vo.CommonNameRegistryService;
import com.pi.pro.xcmg.am.common.XcmgAmConstants;
import com.pi.pro.xcmg.am.was.edi.led.common.LedWasXcmgExchangeConstants;
import com.pi.pro.xcmg.am.was.edi.led.dto.*;
import com.pi.pro.xcmg.am.was.edi.led.service.LedDisplayServiceProxy;
import com.pi.wms.dto.base.LocationLineDto;
import com.pi.wms.entity.TblLedMessage;
import com.pi.wms.entity.TwmBasMaterial;
import com.pi.wms.entity.TwtActTaskList;
import com.pi.wms.entity.TwtActTransList;
import com.pi.wms.fac.LocationResolver;
import com.pi.wms.service.DivisionService;
import com.pi.wms.service.LedMessageService;
import com.pi.wms.service.MaterialService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;


/**
 *
 */
@Slf4j
@Service
public class LedCustomWorkService {

    @Autowired
    private DivisionService divisionService;

    @Autowired
    private MaterialService materialService;

    @Autowired
    private LocationResolver locationResolver;

    @Autowired
    private LedMessageService ledMessageService;

    @Autowired
    private CommonNameRegistryService ledNameRegistryService;

    @Autowired
    private WasCustomWorkService wasCustomWorkService;

    @Autowired
    private WcsCustomWorkService wcsCustomWorkService;


    private Cache<String, TblLedMessage> ledMessageWorkerCache= CacheBuilder.newBuilder().expireAfterWrite(20, TimeUnit.MINUTES).build();


    //
    public R<Void> sendTaskInfo(String divisionCode, LedTaskInfo taskInfo){
        String m="";
        if (taskInfo==null){
            return R.fail("task data is null");
        }
        Long divisionId=this.divisionService.retrieveOn(divisionCode, XcmgAmConstants.DIVISION_WH101_ID);
        //
        LedDisplayServiceProxy proxy = null;
        R<Void> result=null;
        try{
            proxy = this.ledNameRegistryService.takeProxy(XcmgAmConstants.CLIENT_ID_XCMG, divisionId, LedDisplayServiceProxy.class);
            if (proxy == null) {
                m = "not found proxy";
                return R.fail(m);
            }
            result=proxy.showTaskInfo(taskInfo);
        }catch (Exception e){
            e.printStackTrace();
            result=R.fail("send task info error:"+e.getMessage());
        }
        return result;
    }

    //
    public R<Void> sendErrorInfo(String divisionCode, LedErrorInfo errorInfo){
        String m="";
        if (errorInfo==null){
            return R.fail("error data is null");
        }
        Long divisionId=this.divisionService.retrieveOn(divisionCode, XcmgAmConstants.DIVISION_WH101_ID);
        //
        LedDisplayServiceProxy proxy = null;
        R<Void> result=null;
        try{
            proxy = this.ledNameRegistryService.takeProxy(XcmgAmConstants.CLIENT_ID_XCMG, divisionId, LedDisplayServiceProxy.class);
            if (proxy == null) {
                m = "not found proxy";
                return R.fail(m);
            }
            result=proxy.showErrorInfo(errorInfo);
        }catch (Exception e){
            e.printStackTrace();
            result=R.fail("send error info error:"+e.getMessage());
        }
        return result;
    }

    //
    public R<Void> sendDefInfo(String divisionCode, LedDefInfo defInfo){
        String m="";
        if (defInfo==null){
            return R.fail("default data is null");
        }
        Long divisionId=this.divisionService.retrieveOn(divisionCode, XcmgAmConstants.DIVISION_WH101_ID);
        //
        LedDisplayServiceProxy proxy = null;
        R<Void> result=null;
        try{
            proxy = this.ledNameRegistryService.takeProxy(XcmgAmConstants.CLIENT_ID_XCMG, divisionId, LedDisplayServiceProxy.class);
            if (proxy == null) {
                m = "not found proxy";
                return R.fail(m);
            }
            result=proxy.showDefInfo(defInfo);
        }catch (Exception e){
            e.printStackTrace();
            result=R.fail("send default info error:"+e.getMessage());
        }
        return result;
    }

    //-----------------------------------------------------------------------
    //
    //-----------------------------------------------------------------------

    public String showText(Long divsionId, String locationCode, TblLedMessage led, String infoText){
        return this.showText(divsionId, locationCode, led, "", infoText);
    }

    public String showText(Long divsionId, String locationCode, TblLedMessage led, String containerNumber, String infoText){
        String m = "";
        if (StringUtils.isNullOrBlank(locationCode)){
            return m;
        }
        if (divsionId==null){
            divsionId=XcmgAmConstants.DIVISION_WH101_ID;
        }
        String divsioncode=this.divisionService.retrieveOn(divsionId, XcmgAmConstants.DIVISION_WH101_CODE);
        locationCode=locationCode.trim();
        LedErrorInfo errorInfo=null;
        R<Void> result=null;
        try{
            if (led==null){
                led=this.take(divsionId, locationCode);
            }
            if (led==null){
                return m;
            }
            if (LedWasXcmgExchangeConstants.LED_STATUS_CLOSE.equalsIgnoreCase(led.getLedStatus())){
                return m;
            }
            errorInfo=new LedErrorInfo();
            this.load(errorInfo, led);

            errorInfo.setContainerCode(StringUtils.ifNullOrBlank(containerNumber, ""));
            errorInfo.setCheckResult(CodesConstants.COMMON_FLAG_NO);
            errorInfo.setErrorMsg(infoText.trim());
            result = this.sendErrorInfo(divsioncode, errorInfo);
            m=this.errorMessage(result);
        }catch (Exception e){
            e.printStackTrace();
        }
        return m;
    }

    public String showBanner‌(Long divsionId, String locationCode, TblLedMessage led, String text){
        String m = "";
        if (StringUtils.isNullOrBlank(locationCode)){
            return m;
        }
        if (divsionId==null){
            divsionId=XcmgAmConstants.DIVISION_WH101_ID;
        }
        String divsioncode=this.divisionService.retrieveOn(divsionId, XcmgAmConstants.DIVISION_WH101_CODE);
        locationCode=locationCode.trim();
        LedDefInfo defInfo=null;
        R<Void> result=null;
        try{
            if (led==null){
                led=this.take(divsionId, locationCode);
            }
            if (led==null){
                return m;
            }
            if (LedWasXcmgExchangeConstants.LED_STATUS_CLOSE.equalsIgnoreCase(led.getLedStatus())){
                return m;
            }
            defInfo=new LedDefInfo();
            this.load(defInfo, led);

            defInfo.setDefStr(text.trim());
            result = this.sendDefInfo(divsioncode, defInfo);
            m=this.errorMessage(result);
        }catch (Exception e){
            e.printStackTrace();
        }
        return m;
    }

    public String showBanner‌(Long divsionId, String locationCode, String containerNumber, String text){
        String m = "";
        if (StringUtils.isNullOrBlank(locationCode)){
            return m;
        }
        if (StringUtils.isNullOrBlank(text)){
            return m;
        }
        if (StringUtils.isNullOrBlank(containerNumber)){
            containerNumber="";
        }
        locationCode=locationCode.trim();
        text=text.trim();
        TblLedMessage led=null;
        try{
            led=this.take(divsionId, locationCode);
            if (led==null){
                return m;
            }
            if (LedWasXcmgExchangeConstants.LED_STATUS_CLOSE.equalsIgnoreCase(led.getLedStatus())){
                return m;
            }
            m = this.showBanner‌(divsionId, locationCode, led, text);
        }catch (Exception e){
            e.printStackTrace();
        }
        return m;
    }

    public String cleanCache(){
        String m = "";
        try{
            this.ledMessageWorkerCache.invalidateAll();
        }catch (Exception e){
            e.printStackTrace();
            m=e.getMessage();
        }
        return m;
    }

    /**
     *  显示: 拣选口显示默认信息
     * */
    public String showPickStationDefText(Long divsionId, String locationCode){
        String m = "";
        if (StringUtils.isNullOrBlank(locationCode)){
            return m;
        }
        locationCode=locationCode.trim();
        TblLedMessage led=null;
        String infotext=null;
        try{
            led=this.take(divsionId, locationCode);
            if (led==null){
                return m;
            }
            if (LedWasXcmgExchangeConstants.LED_STATUS_CLOSE.equalsIgnoreCase(led.getLedStatus())){
                return m;
            }
            infotext=led.getDf1();
            m = this.showBanner‌(divsionId, locationCode, led, infotext);
        }catch (Exception e){
            e.printStackTrace();
        }
        return m;
    }

    /**
     * 显示: 拣选口显示拣选信息
     */

    public String showPickStationPickTask(Long divsionId, String locationCode, TwtActTaskList task, int total, int index){
        String m = "";
        if (StringUtils.isNullOrBlank(locationCode)){
            return m;
        }
        if (task==null){
            return m;
        }
        if (divsionId==null){
            divsionId=XcmgAmConstants.DIVISION_WH101_ID;
        }
        String divsioncode=this.divisionService.retrieveOn(divsionId, XcmgAmConstants.DIVISION_WH101_CODE);
        locationCode=locationCode.trim();
        TblLedMessage led=null;
        LedTaskInfo taskInfo=null;
        String infotext=null;
        R<Void> result=null;
        LocationLineDto fmloc=null;
        LocationLineDto toloc=null;
        LedItemDetail tline=null;
        List<LedItemDetail> tlines=null;
        TwmBasMaterial material=null;
        try{
            led=this.take(divsionId, locationCode);
            if (led==null){
                return m;
            }
            if (LedWasXcmgExchangeConstants.LED_STATUS_CLOSE.equalsIgnoreCase(led.getLedStatus())){
                return m;
            }
            taskInfo=new LedTaskInfo();
            this.load(taskInfo, led);

            taskInfo.setInOutType(LedWasXcmgExchangeConstants.TASK_TYPE_OUTBOUND);
            taskInfo.setContainerCode(task.getFromContainNumber());
            taskInfo.setSrcLocationCode("");
            fmloc=this.locationResolver.lookup(task.getFromLocId());
            if (fmloc!=null){
                taskInfo.setSrcLocationCode(this.wcsCustomWorkService.takePointcode(fmloc));
            }
            toloc=this.locationResolver.lookup(divsionId, locationCode);
            if (toloc!=null){
                taskInfo.setTargetLocationCode(this.wcsCustomWorkService.takePointcode(toloc));
            }
            taskInfo.setTaskNo(task.getNumber());

            tlines=new ArrayList<>();
            tline=new LedItemDetail();
            material=this.materialService.lookup(task.getMaterialId());
            if (material!=null){
                tline.setItemCode(material.getCode());
                tline.setItemName(material.getName());
            }
            tline.setQty(task.getFromQty());
            tline.setUnitName(material.getPrintUom());
            tline.setWorkSequence(String.valueOf(index)+"/"+String.valueOf(index));
            tline.setWorkPalce(task.getUdf09());
            tline.setDeliveryPlacee(StringUtils.ifNullOrBlank(task.getUdf10(),""));

            tlines.add(tline);
            taskInfo.setDetailList(tlines);
            result = this.sendTaskInfo(divsioncode, taskInfo);
            m=this.errorMessage(result);
        }catch (Exception e){
            e.printStackTrace();
        }
        return m;
    }

    /**
     * 显示: 拣选失败
     */
    public String showPickStationPickError(Long divsionId, String locationCode, String containerNumber, String errorText){
        String m = "";
        if (StringUtils.isNullOrBlank(errorText)){
            m="拣货失败.";
            return m;
        }
        m = this.showText(divsionId, locationCode, null, containerNumber, errorText);
        return m;
    }

    /**
     * 显示: 拣选成功
     */
    public String showPickStationPickSuccess(Long divsionId, String locationCode, String containerNumber, String text){
        String m = "";
        if (StringUtils.isNullOrBlank(text)){
            m="拣货完成.";
            return m;
        }
        m = this.showBanner‌(divsionId, locationCode, containerNumber, text);
        return m;
    }


    public String showPickStationCountTask(Long divsionId, String locationCode, TwtActTaskList task, int total, int index){
        String m = "";
        if (StringUtils.isNullOrBlank(locationCode)){
            return m;
        }
        if (task==null){
            return m;
        }
        if (divsionId==null){
            divsionId=XcmgAmConstants.DIVISION_WH101_ID;
        }
        String divsioncode=this.divisionService.retrieveOn(divsionId, XcmgAmConstants.DIVISION_WH101_CODE);
        locationCode=locationCode.trim();
        TblLedMessage led=null;
        LedTaskInfo taskInfo=null;
        String infotext=null;
        R<Void> result=null;
        LocationLineDto fmloc=null;
        LocationLineDto toloc=null;
        LedItemDetail tline=null;
        List<LedItemDetail> tlines=null;
        TwmBasMaterial material=null;
        try{
            led=this.take(divsionId, locationCode);
            if (led==null){
                return m;
            }
            if (LedWasXcmgExchangeConstants.LED_STATUS_CLOSE.equalsIgnoreCase(led.getLedStatus())){
                return m;
            }
            taskInfo=new LedTaskInfo();
            this.load(taskInfo, led);

            taskInfo.setInOutType(LedWasXcmgExchangeConstants.TASK_TYPE_COUNT);
            taskInfo.setContainerCode(task.getFromContainNumber());
            taskInfo.setSrcLocationCode("");
            fmloc=this.locationResolver.lookup(task.getFromLocId());
            if (fmloc!=null){
                taskInfo.setSrcLocationCode(this.wcsCustomWorkService.takePointcode(fmloc));
            }
            toloc=this.locationResolver.lookup(divsionId, locationCode);
            if (toloc!=null){
                taskInfo.setTargetLocationCode(this.wcsCustomWorkService.takePointcode(toloc));
            }
            taskInfo.setTaskNo(task.getNumber());

            tlines=new ArrayList<>();
            tline=new LedItemDetail();
            material=this.materialService.lookup(task.getMaterialId());
            if (material!=null){
                tline.setItemCode(material.getCode());
                tline.setItemName(material.getName());
            }
            tline.setQty(task.getFromQty());
            tline.setUnitName(material.getPrintUom());
            tline.setWorkSequence(String.valueOf(index)+"/"+String.valueOf(total));
            tline.setWorkPalce("");
            tline.setDeliveryPlacee("");

            tlines.add(tline);
            taskInfo.setDetailList(tlines);
            result = this.sendTaskInfo(divsioncode, taskInfo);
            m=this.errorMessage(result);
        }catch (Exception e){
            e.printStackTrace();
        }
        return m;
    }

    /**
     *  显示: 入库口显示默认信息
     * */
    public String showPutawayStationDefText(Long divsionId, String locationCode){
        String m = "";
        if (StringUtils.isNullOrBlank(locationCode)){
            return m;
        }
        locationCode=locationCode.trim();
        TblLedMessage led=null;
        String infotext=null;
        try{
            led=this.take(divsionId, locationCode);
            if (led==null){
                return m;
            }
            if (LedWasXcmgExchangeConstants.LED_STATUS_CLOSE.equalsIgnoreCase(led.getLedStatus())){
                return m;
            }
            infotext=led.getDf1();
            if (!StringUtils.isNullOrBlank(led.getDf2())){
                infotext=infotext+";"+led.getDf2().trim();
            }
            if (!StringUtils.isNullOrBlank(led.getDf3())){
                infotext=infotext+";"+led.getDf3().trim();
            }
            if (!StringUtils.isNullOrBlank(led.getDf4())){
                infotext=infotext+";"+led.getDf4().trim();
            }
            m = this.showBanner‌(divsionId, locationCode, led, infotext);
        }catch (Exception e){
            e.printStackTrace();
        }
        return m;
    }

    public String showPutawayStationPutawayTask(Long divsionId, String locationCode, TwtActTaskList task){
        String m = "";
        if (StringUtils.isNullOrBlank(locationCode)){
            return m;
        }
        if (task==null){
            return m;
        }
        if (divsionId==null){
            divsionId=XcmgAmConstants.DIVISION_WH101_ID;
        }
        String divsioncode=this.divisionService.retrieveOn(divsionId, XcmgAmConstants.DIVISION_WH101_CODE);
        locationCode=locationCode.trim();
        TblLedMessage led=null;
        LedTaskInfo taskInfo=null;
        String infotext=null;
        R<Void> result=null;
        LocationLineDto fmloc=null;
        LocationLineDto toloc=null;
        LedItemDetail tline=null;
        List<LedItemDetail> tlines=null;
        TwmBasMaterial material=null;
        try{
            led=this.take(divsionId, locationCode);
            if (led==null){
                return m;
            }
            if (LedWasXcmgExchangeConstants.LED_STATUS_CLOSE.equalsIgnoreCase(led.getLedStatus())){
                return m;
            }
            taskInfo=new LedTaskInfo();
            this.load(taskInfo, led);

            taskInfo.setInOutType(LedWasXcmgExchangeConstants.TASK_TYPE_INBOUND);
            taskInfo.setContainerCode(task.getFromContainNumber());
            taskInfo.setSrcLocationCode("");
            fmloc=this.locationResolver.lookup(task.getFromLocId());
            if (fmloc!=null){
                taskInfo.setSrcLocationCode(this.wcsCustomWorkService.takePointcode(fmloc));
            }
            toloc=this.locationResolver.lookup(divsionId, locationCode);
            if (toloc!=null){
                taskInfo.setTargetLocationCode(this.wcsCustomWorkService.takePointcode(toloc));
            }
            taskInfo.setTaskNo(task.getNumber());

            tlines=new ArrayList<>();
            tline=new LedItemDetail();
            material=this.materialService.lookup(task.getMaterialId());
            if (material!=null){
                tline.setItemCode(material.getCode());
                tline.setItemName(material.getName());
            }
            tline.setQty(task.getFromQty());
            tline.setUnitName(material.getPrintUom());

            tlines.add(tline);
            taskInfo.setDetailList(tlines);
            result = this.sendTaskInfo(divsioncode, taskInfo);
            m=this.errorMessage(result);
        }catch (Exception e){
            e.printStackTrace();
        }
        return m;
    }



    /**
     * 显示: 入库失败
     */
    public String showPutawayStationExecuteError(Long divsionId, String locationCode, String containerNumber, String errorText){
        String m = "";
        if (StringUtils.isNullOrBlank(errorText)){
            m="入库失败.";
            return m;
        }
        m = this.showText(divsionId, locationCode, null, containerNumber, errorText);
        return m;
    }

    /**
     * 显示: 入库成功
     */
    public String showPutawayStationExecuteSuccess(Long divsionId, String locationCode, String containerNumber, String text){
        String m = "";
        if (StringUtils.isNullOrBlank(text)){
            m="入库成功.";
            return m;
        }
        m = this.showText(divsionId, locationCode, null, containerNumber, text);
        return m;
    }

    public TblLedMessage take(Long divisionId, String locationCode){
        TblLedMessage led=null;
        if (StringUtils.isNullOrBlank(locationCode)){
            return led;
        }
        String divisionCode=this.divisionService.retrieveOn(divisionId, XcmgAmConstants.DIVISION_WH101_CODE);
        String fullcode=divisionCode+"/"+locationCode.trim();
        led=this.ledMessageWorkerCache.getIfPresent(fullcode);
        if (led!=null){
            return led;
        }
        try{
            led=this.ledMessageService.findByFullcode(fullcode);
            if (led==null){
                return led;
            }
            this.ledMessageWorkerCache.put(fullcode, led);
        }catch (Exception e){
            e.getMessage();
        }
        return led;
    }

    private void load(ConntectionLedData conntectionLedData, TblLedMessage led){
        if (conntectionLedData==null){
            return;
        }
        if (led==null){
            return;
        }
        conntectionLedData.setIp(led.getIp());
        conntectionLedData.setPort(led.getPortNumber());
    }

    private String errorMessage(R<Void> result){
        String m="";
        if (result==null){
            m="未收到LED反馈.";
            return m;
        }
        if (result.getCode()==R.SUCCESS){
            return m;
        }
        m="发送失败.";
        if (!StringUtils.isNullOrBlank(result.getMsg())){
            m=result.getMsg();
        }
        return m;
    }

}
